﻿using CNFM_CROCODILE_LOGO.Core.Domain.Current;
using CNFM_CROCODILE_LOGO.Core.Domain.Entity;
using CNFM_CROCODILE_LOGO.Core.Domain.ViewModels;
using CNFM_CROCODILE_LOGO.Core.Repository;
using CNFM_CROCODILE_LOGO.Data.RestClient;
using CNFM_CROCODILE_LOGO.RestClient.Utils;
using CNFM_CROCODILE_LOGO.Services.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CNFM_CROCODILE_LOGO.Services.Implementations
{
    /// <summary>
    /// 汇总分析
    /// </summary>
    public class SummaryReportServices : ISummaryReportServices
    {
        private IEfRepository _rep;

        public SummaryReportServices(IEfRepository rep)
        {
            this._rep = rep;
        }

        /// <summary>
        /// 区域汇总
        /// </summary>
        /// <param name="areaCode"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public ReturnValueModel GetAreaReport(string areaCode, string startDate, string endDate, string enterpriseId, int type = 1)
        {
            var arr = AreaAll(areaCode);
            var list = from a in _rep.Where<SignageApplicationReceipt>(p => p.Status != -1)
                       join e in _rep.Where<Enterprise>(p => p.Status == 0) on a.EnterpriseId equals e.Id
                       join r in _rep.Where<Area>(p => p.Status == 0) on e.UnCode equals r.YUnCode
                       where !string.IsNullOrEmpty(areaCode) && areaCode != "null" && areaCode != "undefined" ? arr.Contains(r.YUnCode) : r.Status == 0
                       select new
                       {
                           a.Id,
                           a.ApplyNum,
                           a.TwoToExamineNum,
                           a.ThreeToExamineNum,
                           r.AreaName,
                           a.RegisteredTime,
                           //UseNum = list1.Where(p => p.SignageApplicationReceiptId == a.Id).Count()
                       };

            var all = list.WhereIf(p => p.RegisteredTime >= Convert.ToDateTime(startDate) && p.RegisteredTime <= Convert.ToDateTime(endDate),
                (string.IsNullOrEmpty(startDate) || string.IsNullOrEmpty(endDate)) == false)
                .WhereIf(p => p.Id == enterpriseId, string.IsNullOrEmpty(enterpriseId) == false)
                 .GroupBy(m => new { m.AreaName })
                .Select(p => new AreaReportModels
                {
                    Name = p.Key.AreaName,
                    ApplyNum = p.Sum(a => a.ApplyNum),
                    TwoToExamineNum = p.Sum(a => a.TwoToExamineNum),
                    ThreeToExamineNum = p.Sum(a => a.ThreeToExamineNum),
                    // UseNum = p.Sum(a => a.UseNum)
                });

            // var modelsSql = all.ToSql();
            var models = all.ToList();

            foreach (var item in models)
            {
                item.UseNum = _rep.Where<LogoStock>(p => p.Status == 2)
                        .Join(_rep.Where<Enterprise>(p => p.Status == 0), a => a.EnterpriseId, e => e.Id, (a, e) => new { a.Id, e.UnCode })
                        .Join(_rep.Where<Area>(p => p.AreaName == item.Name), a => a.UnCode, r => r.YUnCode, (a, r) => new { a.Id }).Count();
            }

            if (type == 0)
            {
                return new ReturnValueModel
                {
                    Code = 200,
                    Msg = "success!",
                    Result = new
                    {
                        Data = models
                    }
                };
            }

            List<ReportModels> reportAll = new List<ReportModels>();
            foreach (var item in models)
            {
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.ApplyNum.ToString(), Type = "申请数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.TwoToExamineNum.ToString(), Type = "审批数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.ThreeToExamineNum.ToString(), Type = "配发数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.UseNum.ToString(), Type = "使用数量" });
            }
            return new ReturnValueModel
            {
                Code = 200,
                Msg = "success!",
                Result = new
                {
                    Data = reportAll
                }
            };
        }

        /// <summary>
        /// 产品配发类型分析
        /// </summary>
        /// <param name="areaCode"></param>
        /// <param name="smType"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <param name="enterpriseId"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public ReturnValueModel GetSpeciesManageTypeReport(string areaCode, string smType, string startDate, string endDate, string enterpriseId, int type = 1)
        {
            var arr = AreaAll(areaCode);
            var list = from a in _rep.Where<LogoStock>(p => p.Status != 0)
                       join e in _rep.Where<Enterprise>(p => p.Status == 0) on a.EnterpriseId equals e.Id
                       join r in _rep.Where<Area>(p => p.Status == 0) on e.UnCode equals r.YUnCode
                       where !string.IsNullOrEmpty(areaCode) && areaCode != "null" && areaCode != "undefined" ? arr.Contains(r.YUnCode) : r.Status == 0
                       join s in _rep.Where<SpeciesManage>(p => p.Status == 0) on a.SpeciesManageId equals s.Id
                       join d in _rep.Where<Dictionary>(p => p.Status == 0) on s.Type equals d.Id
                       select new
                       {
                           a.Id,
                           a.EnterpriseId,
                           a.CreateTime,
                           s.SpeciesName,
                           d.Name,
                           s.Type,
                       };

            var all = list.WhereIf(p => p.CreateTime >= Convert.ToDateTime(startDate) && p.CreateTime <= Convert.ToDateTime(endDate),
               (string.IsNullOrEmpty(startDate) || string.IsNullOrEmpty(endDate)) == false)
               .WhereIf(p => p.Id == enterpriseId, string.IsNullOrEmpty(enterpriseId) == false)
                .GroupBy(m => new { m.Name })
               .Select(p => new
               {
                   Type = p.Key.Name,
                   Total = p.Count()
                   // UseNum = p.Sum(a => a.UseNum)
               });

            var models = all.ToList();
            if (type == 0)
            {
                return new ReturnValueModel
                {
                    Code = 200,
                    Msg = "success!",
                    Result = new
                    {
                        Data = models
                    }
                };
            }

            List<ReportModels> reportAll = new List<ReportModels>();
            var speciesManageList = _rep.Where<SpeciesManage>(p => true);
            foreach (var item in models)
            {
                reportAll.Add(new ReportModels { Name = item.Type, Value = item.Total.ToString()});
            }
            return new ReturnValueModel
            {
                Code = 200,
                Msg = "success!",
                Result = new
                {
                    Data = reportAll
                }
            };

        }

        /// <summary>
        /// 企业汇总分析
        /// </summary>
        /// <param name="areaCode"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public ReturnValueModel GetEnterpriseReport(string areaCode, string startDate, string endDate, string enterpriseId, int type = 1)
        {
            var arr = AreaAll(areaCode);

            var list = from a in _rep.Where<SignageApplicationReceipt>(p => p.Status != -1)
                       join e in _rep.Where<Enterprise>(p => p.Status == 0) on a.EnterpriseId equals e.Id
                       join r in _rep.Where<Area>(p => p.Status == 0) on e.UnCode equals r.YUnCode
                       where !string.IsNullOrEmpty(areaCode) && areaCode != "null" && areaCode != "undefined" ? arr.Contains(r.YUnCode) : r.Status == 0
                       select new
                       {
                           a.Id,
                           a.ApplyNum,
                           a.TwoToExamineNum,
                           a.ThreeToExamineNum,
                           e.EnterpriseName,
                           a.RegisteredTime,
                           // UseNum = _rep.Where<Identification>(p => p.Status == 1 && p.SignageApplicationReceiptId == a.Id).Count()
                       };


            var all = list.WhereIf(p => p.RegisteredTime >= Convert.ToDateTime(startDate) && p.RegisteredTime <= Convert.ToDateTime(endDate),
                (string.IsNullOrEmpty(startDate) || string.IsNullOrEmpty(endDate)) == false)
                 .WhereIf(p => p.Id == enterpriseId, string.IsNullOrEmpty(enterpriseId) == false)
                .GroupBy(m => new { m.EnterpriseName })
                .Select(p => new AreaReportModels
                {
                    Name = p.Key.EnterpriseName,
                    ApplyNum = p.Sum(a => a.ApplyNum),
                    TwoToExamineNum = p.Sum(a => a.TwoToExamineNum),
                    ThreeToExamineNum = p.Sum(a => a.ThreeToExamineNum)
                });

            var models = all.ToList();
            foreach (var item in models)
            {
                item.UseNum = _rep.Where<LogoStock>(p => p.Status == 2)
                    .Join(_rep.Where<Enterprise>(p => p.Status == 0 && p.EnterpriseName == item.Name), a => a.EnterpriseId, e => e.Id, (a, e) => new { a.Id, e.UnCode })
                    .Join(_rep.Where<Area>(p => p.Status == 0), a => a.UnCode, r => r.YUnCode, (a, r) => new { a.Id }).Count();
            }
            if (type == 0)
            {
                return new ReturnValueModel
                {
                    Code = 200,
                    Msg = "success!",
                    Result = new
                    {
                        Data = models
                    }
                };
            }

            List<ReportModels> reportAll = new List<ReportModels>();
            foreach (var item in models)
            {
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.ApplyNum.ToString(), Type = "申请数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.TwoToExamineNum.ToString(), Type = "审批数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.ThreeToExamineNum.ToString(), Type = "配发数量" });
                reportAll.Add(new ReportModels { Name = item.Name, Value = item.UseNum.ToString(), Type = "使用数量" });
            }
            return new ReturnValueModel
            {
                Code = 200,
                Msg = "success!",
                Result = new
                {
                    Data = reportAll
                }
            };
        }

        /// <summary>
        /// 标识汇总分析
        /// </summary>
        /// <param name="areaCode"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public ReturnValueModel GetApplicationReport(string areaCode, string enterpriseId)
        {
            var arr = AreaAll(areaCode);
            var list = from a in _rep.Where<LogoStock>(p => true)
                       where !string.IsNullOrEmpty(enterpriseId) ? a.Id == enterpriseId : a.Status != -6
                       join e in _rep.Where<Enterprise>(p => p.Status == 0) on a.EnterpriseId equals e.Id
                       join r in _rep.Where<Area>(p => p.Status == 0) on e.UnCode equals r.YUnCode
                       where !string.IsNullOrEmpty(areaCode) && areaCode != "null" && areaCode != "undefined" ? arr.Contains(r.YUnCode) : r.Status == 0
                       select new
                       {
                           a.Id,
                           a.Status,
                           e.EnterpriseName,
                           r.AreaName
                           // UseNum = _rep.Where<Identification>(p => p.Status == 1 && p.SignageApplicationReceiptId == a.Id).Count()
                       };


            List<ReportModels> reportAll = new List<ReportModels>();
            reportAll.Add(new ReportModels { Name = "配发总数", Value = list.Count().ToString() });
            reportAll.Add(new ReportModels { Name = "使用总数", Value = list.Where(p => p.Status == 2).Count().ToString() });
            reportAll.Add(new ReportModels { Name = "作废总数", Value = list.Where(p => p.Status == -1).Count().ToString() });

            return new ReturnValueModel
            {
                Code = 200,
                Msg = "success!",
                Result = new
                {
                    Data = reportAll
                }
            };
        }


        public string[] AreaAll(string UnCode)
        {
            //权限数据
            var sql1 = string.Empty;
            List<string> arrt3 = new List<string>();
            string[] arrt4;
            if (!string.IsNullOrEmpty(UnCode) && UnCode != "undefined" && UnCode != "null")
            {
                sql1 = "WITH CTE AS ( SELECT YUnCode,PUnCode FROM dbo.Area WHERE YUnCode={0} AND Status=0 UNION ALL SELECT a.YUnCode,a.PUnCode FROM dbo.Area a INNER JOIN CTE b ON b.YUnCode=a.PUnCode) SELECT a.*  FROM dbo.Area a INNER JOIN CTE t ON a.YUnCode=t.YUnCode";
                var areaAll = _rep.SqlQuery<Area>(sql1, UnCode).ToList();

                foreach (var item in areaAll)
                    arrt3.Add(item.YUnCode);
                arrt4 = arrt3.ToArray();
            }
            else
            {
                sql1 = "WITH CTE AS ( SELECT YUnCode,PUnCode FROM dbo.Area WHERE PUnCode={0} AND Status=0 UNION ALL SELECT a.YUnCode,a.PUnCode FROM dbo.Area a INNER JOIN CTE b ON b.YUnCode=a.PUnCode) SELECT a.*  FROM dbo.Area a INNER JOIN CTE t ON a.YUnCode=t.YUnCode";
                var areaAll = _rep.SqlQuery<Area>(sql1, 0).ToList();

                foreach (var item in areaAll)
                    arrt3.Add(item.YUnCode);
                arrt4 = arrt3.ToArray();
            }

            return arrt4;
        }
    }
}
